package com.example.asapp.socket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
    @auth fbz
    @date 2021/3/18 0018/下午 4:05
*/
@Component
@Slf4j
@ServerEndpoint("/socket/{name}")
public class WebSocketServer {
    /**
     * 全部在线会话
     */
    private static Map<String, Session> onlineSessions = new ConcurrentHashMap<>();

    // 如果现在登陆的客户有很多 那就智能
    // 存放session与userId,<sessionId, userId>
    /**
     * 当客户端打开连接：1.添加会话对象 2.更新在线人数
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("name") String name) {
        // 建立链接 获取fbz
        log.info("name is {}",session.getId());
        onlineSessions.put(session.getId(), session);

    }

    /**
     * 当客户端发送消息：1.获取它的用户名和消息 2.发送消息给所有人
     * <p>
     * PS: 这里约定传递的消息为JSON字符串 方便传递更多参数！
     */

    @OnMessage
    public void onMessage(Session session, String jsonStr,@PathParam("name") String name) {
        log.info("id ({}) send jsonStr:{}",session.getId(), jsonStr);
    }

    /**
     * 当关闭连接：1.移除会话对象 2.更新在线人数
     */
    @OnClose
    public void onClose(Session session,@PathParam("name") String name) {
        onlineSessions.remove(session.getId());
    }

    /**
     * 当通信发生异常：打印错误日志
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * 公共方法：发送信息给所有人
     */
    /*
     * 生成redis在链接中
     * 向指定的用户发送
     */
    public void sendMessageToAll(String jsonMsg) {
        log.info("已连接的单位有:{}",onlineSessions.size());
        onlineSessions.forEach((id, session) -> {
            try {
                log.info("id is {}",id);
                session.getBasicRemote().sendText(jsonMsg);
            } catch (IOException e) {
                log.info("error");
                e.printStackTrace();
            }
        });
    }

}